home *** CD-ROM | disk | FTP | other *** search
/ Enigma Amiga Life 109 / EnigmaAmiga109CD.iso / dalla rivista / host contacted / jikes.lha / jikes-1.11 / src / system.cpp < prev    next >
C/C++ Source or Header  |  2000-01-16  |  37KB  |  939 lines

  1. // $Id: system.cpp,v 1.23 1999/11/18 03:37:23 shields Exp $
  2. //
  3. // This software is subject to the terms of the IBM Jikes Compiler
  4. // License Agreement available at the following URL:
  5. // http://www.ibm.com/research/jikes.
  6. // Copyright (C) 1996, 1998, International Business Machines Corporation
  7. // and others.  All Rights Reserved.
  8. // You must accept the terms of that agreement to use this software.
  9. //
  10. #include "config.h"
  11. #include <sys/stat.h>
  12. #include "control.h"
  13. #include "semantic.h"
  14. #include "zip.h"
  15.  
  16. //
  17. // Convert the null terminated Unicode string source into its Utf8
  18. // representation pointed to by target. The char string target is presumed
  19. // to have been allocated and to be large enough to accomodate the conversion.
  20. //
  21. int Control::ConvertUnicodeToUtf8(wchar_t *source, char *target)
  22. {
  23.     int length = 0;
  24.  
  25.     for (; *source; source++)
  26.     {
  27.         int ch = *source;
  28.  
  29.         if (ch == 0)
  30.         {
  31.              target[length++] = (char) 0xC0;
  32.              target[length++] = (char) 0x80;
  33.         }
  34.         else if (ch <= 0x007F)
  35.              target[length++] = (char) ch;
  36.         else if (ch <= 0x07FF)
  37.         {
  38.              target[length++] = (char) ((char) 0xC0 | (char) ((ch >> 6) & 0x001F)); // bits 6-10
  39.              target[length++] = (char) ((char) 0x80 | (char) (ch & 0x003F));        // bits 0-5
  40.         }
  41.         else
  42.         {
  43.              target[length++] = (char) ((char) 0xE0 | (char) ((ch >> 12) & 0x000F));
  44.              target[length++] = (char) ((char) 0x80 | (char) ((ch >> 6) & 0x003F));
  45.              target[length++] = (char) ((char) 0x80 | (char) (ch & 0x3F));
  46.         }
  47.     }
  48.     target[length] = U_NULL;
  49.  
  50.     return length;
  51. }
  52.  
  53.  
  54. //
  55. // Convert the Utf8 string of length len pointed to by source into its unicode
  56. // representation pointed to by target. The wchar_t string target is presumed
  57. // to have been allocated and to be large enough (at least len + 1) to accomodate
  58. // the conversion.
  59. //
  60. int Control::ConvertUtf8ToUnicode(wchar_t *target, char *source, int len)
  61. {
  62.     wchar_t *ptr = target;
  63.     for (int i = 0; i < len; i++, ptr++)
  64.     {
  65.         u1 ch = source[i];
  66.  
  67.         if ((ch & 0x80) == 0)
  68.             *ptr = ch;
  69.         else if ((ch & 0xE0) == 0xC0)
  70.         {
  71.             *ptr = ch & 0x1F;
  72.             *ptr <<= 6;
  73.             i++;
  74.             ch = source[i] & 0x3F;
  75.             *ptr += ch;
  76.         }
  77.         else if ((ch & 0xF0) == 0xE0)
  78.         {
  79.             *ptr = ch & 0x0F;
  80.             *ptr <<= 6;
  81.             i++;
  82.             ch = source[i] & 0x3F;
  83.             *ptr += ch;
  84.  
  85.             *ptr <<= 6;
  86.             i++;
  87.             ch = source[i] & 0x3F;
  88.             *ptr += ch;
  89.         }
  90.         else
  91.         {
  92.             assert(! "valid character encoding: chaos, Damn, Caramba, Zut !!!\n");
  93.         }
  94.     }
  95.  
  96.     *ptr = U_NULL;
  97.  
  98.     return (ptr - target);
  99. }
  100.  
  101.  
  102. void Control::FindPathsToDirectory(PackageSymbol *package)
  103. {
  104.     if (package -> directory.Length() == 0)
  105.     {
  106.         PackageSymbol *owner_package = package -> owner;
  107.         if (owner_package) // package is a subpackage?
  108.         {
  109.             for (int i = 0; i < owner_package -> directory.Length(); i++)
  110.             {
  111.                 DirectorySymbol *owner_directory_symbol = owner_package -> directory[i],
  112.                                 *subdirectory_symbol = owner_directory_symbol -> FindDirectorySymbol(package -> Identity());
  113.                 if (! owner_directory_symbol -> IsZip())
  114.                 {
  115.                     if (! subdirectory_symbol)
  116.                     {
  117.                         int length = owner_directory_symbol -> DirectoryNameLength() + package -> Utf8NameLength() + 1; // +1 for '/'
  118.                         char *directory_name = new char[length + 1]; // +1 for '\0';
  119.  
  120.                         strcpy(directory_name, owner_directory_symbol -> DirectoryName());
  121.                         if (owner_directory_symbol -> DirectoryName()[owner_directory_symbol -> DirectoryNameLength() - 1] != U_SLASH)
  122.                             strcat(directory_name, StringConstant::U8S__SL);
  123.                         strcat(directory_name, package -> Utf8Name());
  124.  
  125.                         if (::SystemIsDirectory(directory_name))
  126.                             subdirectory_symbol = owner_directory_symbol -> InsertDirectorySymbol(package -> Identity());
  127.  
  128.                         delete [] directory_name;
  129.                     }
  130.  
  131.                     if (subdirectory_symbol)
  132.                         subdirectory_symbol -> ReadDirectory();
  133.                 }
  134.  
  135.                 if (subdirectory_symbol)
  136.                     package -> directory.Next() = subdirectory_symbol;
  137.             }
  138.         }
  139.         else
  140.         {
  141.             //
  142.             // Recall that since classpath[0] contains the default directory, we always
  143.             // start searching at location 1.
  144.             //
  145.             for (int k = 1; k < classpath.Length(); k++)
  146.             {
  147.                 PathSymbol *path_symbol = classpath[k];
  148.                 DirectorySymbol *directory_symbol = path_symbol -> RootDirectory() -> FindDirectorySymbol(package -> Identity());
  149.                 if (! path_symbol -> IsZip())
  150.                 {
  151.                     if (! directory_symbol)
  152.                     {
  153.                         int length = path_symbol -> Utf8NameLength() + package -> Utf8NameLength() + 1; // +1 for '/'
  154.                         char *directory_name = new char[length + 1]; // +1 for '\0'
  155.                         strcpy(directory_name, path_symbol -> Utf8Name());
  156.                         char tail = path_symbol -> Utf8Name()[path_symbol -> Utf8NameLength() - 1];
  157.                         if (tail != U_SLASH && tail != U_BACKSLASH)
  158.                             strcat(directory_name, StringConstant::U8S__SL);
  159.                         strcat(directory_name, package -> Utf8Name());
  160.  
  161.                         if (::SystemIsDirectory(directory_name))
  162.                             directory_symbol = path_symbol -> RootDirectory() -> InsertDirectorySymbol(package -> Identity());
  163.                         delete [] directory_name;
  164.                     }
  165.  
  166.                     if (directory_symbol)
  167.                         directory_symbol -> ReadDirectory();
  168.                 }
  169.  
  170.                 if (directory_symbol)
  171.                     package -> directory.Next() = directory_symbol;
  172.             }
  173.         }
  174.     }
  175.  
  176.     return;
  177. }
  178.  
  179.  
  180. void Control::ProcessGlobals()
  181. {
  182.     dot_name_symbol        = FindOrInsertName(US__DO, wcslen(US__DO));
  183.     dot_dot_name_symbol    = FindOrInsertName(US__DO__DO, wcslen(US__DO__DO));
  184.     length_name_symbol     = FindOrInsertName(US_length, wcslen(US_length));
  185.     init_name_symbol       = FindOrInsertName(US__LT_init_GT, wcslen(US__LT_init_GT));
  186.     clinit_name_symbol     = FindOrInsertName(US__LT_clinit_GT, wcslen(US__LT_clinit_GT));
  187.     block_init_name_symbol = FindOrInsertName(US_block_DOLLAR, wcslen(US_block_DOLLAR));
  188.     this0_name_symbol      = FindOrInsertName(US_this0, wcslen(US_this0));
  189.     clone_name_symbol      = FindOrInsertName(US_clone, wcslen(US_clone));
  190.     object_name_symbol     = FindOrInsertName(US_Object, wcslen(US_Object));
  191.     type_name_symbol       = FindOrInsertName(US_TYPE, wcslen(US_TYPE));
  192.     class_name_symbol      = FindOrInsertName(US__class_DOLLAR, wcslen(US__class_DOLLAR));
  193.     toString_name_symbol   = FindOrInsertName(US_toString, wcslen(US_toString));
  194.     append_name_symbol     = FindOrInsertName(US_append, wcslen(US_append));
  195.     forName_name_symbol    = FindOrInsertName(US_forName, wcslen(US_forName));
  196.     getMessage_name_symbol = FindOrInsertName(US_getMessage, wcslen(US_getMessage));
  197.  
  198.     ConstantValue_literal = Utf8_pool.FindOrInsert(U8S_ConstantValue, U8S_ConstantValue_length);
  199.     Exceptions_literal = Utf8_pool.FindOrInsert(U8S_Exceptions, U8S_Exceptions_length);
  200.     InnerClasses_literal = Utf8_pool.FindOrInsert(U8S_InnerClasses, U8S_InnerClasses_length);
  201.     Synthetic_literal = Utf8_pool.FindOrInsert(U8S_Synthetic, U8S_Synthetic_length);
  202.     Deprecated_literal = Utf8_pool.FindOrInsert(U8S_Deprecated, U8S_Deprecated_length);
  203.     LineNumberTable_literal = Utf8_pool.FindOrInsert(U8S_LineNumberTable, U8S_LineNumberTable_length);
  204.     LocalVariableTable_literal = Utf8_pool.FindOrInsert(U8S_LocalVariableTable, U8S_LocalVariableTable_length);
  205.     Code_literal = Utf8_pool.FindOrInsert(U8S_Code, U8S_Code_length);
  206.     Sourcefile_literal = Utf8_pool.FindOrInsert(U8S_Sourcefile, U8S_Sourcefile_length);
  207.  
  208.     null_literal = Utf8_pool.FindOrInsert(U8S_null, U8S_null_length);
  209.     this_literal = Utf8_pool.FindOrInsert(U8S_this, U8S_this_length);
  210.  
  211.     return;
  212. }
  213.  
  214.  
  215. void Control::InitClassInfo()
  216. {
  217.     if (! Class_type -> Bad())
  218.     {
  219.         //
  220.         // Search for relevant forName method
  221.         //
  222.         for (MethodSymbol *method = Class_type -> FindMethodSymbol(forName_name_symbol);
  223.              method;
  224.              method = method -> next_method)
  225.         {
  226.             char *signature = method -> SignatureString();
  227.  
  228.             if (strcmp(signature, StringConstant::U8S_LP_Ljava_SL_lang_SL_String_SC_RP_Ljava_SL_lang_SL_Class_SC) == 0)
  229.             {
  230.                 Class_forName_method = method;
  231.                 break;
  232.             }
  233.         }
  234.  
  235.         if (! Class_forName_method)
  236.         {
  237.             system_semantic -> ReportSemError(SemanticError::NON_STANDARD_LIBRARY_TYPE,
  238.                                               0,
  239.                                               0,
  240.                                               Class_type -> ContainingPackage() -> PackageName(),
  241.                                               Class_type -> ExternalName());
  242.         }
  243.     }
  244.  
  245.     return;
  246. }
  247.  
  248.  
  249. void Control::InitThrowableInfo()
  250. {
  251.     if (! Throwable_type -> Bad())
  252.     {
  253.         //
  254.         // Search for relevant getMessage method
  255.         //
  256.         for (MethodSymbol *method = Throwable_type -> FindMethodSymbol(getMessage_name_symbol);
  257.              method;
  258.              method = method -> next_method)
  259.         {
  260.             char *signature = method -> SignatureString();
  261.  
  262.             if (strcmp(signature, StringConstant::U8S_LP_RP_Ljava_SL_lang_SL_String_SC) == 0)
  263.             {
  264.                 Throwable_getMessage_method = method;
  265.                 break;
  266.             }
  267.         }
  268.  
  269.         if (! Throwable_getMessage_method)
  270.         {
  271.             system_semantic -> ReportSemError(SemanticError::NON_STANDARD_LIBRARY_TYPE,
  272.                                               0,
  273.                                               0,
  274.                                               Throwable_type -> ContainingPackage() -> PackageName(),
  275.                                               Throwable_type -> ExternalName());
  276.         }
  277.     }
  278.  
  279.     return;
  280. }
  281.  
  282.  
  283. void Control::InitNoClassDefFoundErrorInfo()
  284. {
  285.     if (! NoClassDefFoundError_type -> Bad())
  286.     {
  287.         //
  288.         // Search for relevant constructors
  289.         //
  290.         for (MethodSymbol *constructor = NoClassDefFoundError_type -> FindConstructorSymbol();
  291.              constructor;
  292.              constructor = constructor -> next_method)
  293.         {
  294.             char *signature = constructor -> SignatureString();
  295.  
  296.             if (strcmp(signature, StringConstant::U8S_LP_Ljava_SL_lang_SL_String_SC_RP_V) == 0)
  297.                 NoClassDefFoundError_InitWithString_method = constructor;
  298.         }
  299.  
  300.         if (! NoClassDefFoundError_InitWithString_method)
  301.         {
  302.             system_semantic -> ReportSemError(SemanticError::NON_STANDARD_LIBRARY_TYPE,
  303.                                               0,
  304.                                               0,
  305.                                               NoClassDefFoundError_type -> ContainingPackage() -> PackageName(),
  306.                                               NoClassDefFoundError_type -> ExternalName());
  307.         }
  308.     }
  309.  
  310.     return;
  311. }
  312.  
  313.  
  314. void Control::InitStringBufferInfo()
  315. {
  316.     if (! StringBuffer_type -> Bad())
  317.     {
  318.         //
  319.         // Search for relevant constructors
  320.         //
  321.         for (MethodSymbol *constructor = StringBuffer_type -> FindConstructorSymbol();
  322.              constructor;
  323.              constructor = constructor -> next_method)
  324.         {
  325.             char *signature = constructor -> SignatureString();
  326.  
  327.             if (strcmp(signature, StringConstant::U8S_LP_RP_V) == 0)
  328.                  StringBuffer_Init_method = constructor;
  329.             else if (strcmp(signature, StringConstant::U8S_LP_Ljava_SL_lang_SL_String_SC_RP_V) == 0)
  330.                  StringBuffer_InitWithString_method = constructor;
  331.         }
  332.  
  333.         //
  334.         // Search for relevant toString method
  335.         //
  336.         for (MethodSymbol *toString_method = StringBuffer_type -> FindMethodSymbol(toString_name_symbol);
  337.              toString_method;
  338.              toString_method = toString_method -> next_method)
  339.         {
  340.             if (strcmp(toString_method -> SignatureString(), StringConstant::U8S_LP_RP_Ljava_SL_lang_SL_String_SC) == 0)
  341.             {
  342.                 StringBuffer_toString_method = toString_method;
  343.                 break;
  344.             }
  345.         }
  346.  
  347.         //
  348.         // Search for relevant append method
  349.         //
  350.         for (MethodSymbol *append_method = StringBuffer_type -> FindMethodSymbol(append_name_symbol);
  351.              append_method;
  352.              append_method = append_method -> next_method)
  353.         {
  354.             char *signature = append_method -> SignatureString();
  355.  
  356.             if (strcmp(signature, StringConstant::U8S_LP_LB_C_RP_Ljava_SL_lang_SL_StringBuffer_SC) == 0)
  357.                  StringBuffer_append_char_array_method = append_method;
  358.             else if (strcmp(signature, StringConstant::U8S_LP_C_RP_Ljava_SL_lang_SL_StringBuffer_SC) == 0)
  359.                  StringBuffer_append_char_method = append_method;
  360.             else if (strcmp(signature, StringConstant::U8S_LP_Z_RP_Ljava_SL_lang_SL_StringBuffer_SC) == 0)
  361.                  StringBuffer_append_boolean_method = append_method;
  362.             else if (strcmp(signature, StringConstant::U8S_LP_I_RP_Ljava_SL_lang_SL_StringBuffer_SC) == 0)
  363.                  StringBuffer_append_int_method = append_method;
  364.             else if (strcmp(signature, StringConstant::U8S_LP_J_RP_Ljava_SL_lang_SL_StringBuffer_SC) == 0)
  365.                  StringBuffer_append_long_method = append_method;
  366.             else if (strcmp(signature, StringConstant::U8S_LP_F_RP_Ljava_SL_lang_SL_StringBuffer_SC) == 0)
  367.                  StringBuffer_append_float_method = append_method;
  368.             else if (strcmp(signature, StringConstant::U8S_LP_D_RP_Ljava_SL_lang_SL_StringBuffer_SC) == 0)
  369.                  StringBuffer_append_double_method = append_method;
  370.             else if (strcmp(signature, StringConstant::U8S_LP_Ljava_SL_lang_SL_String_SC_RP_Ljava_SL_lang_SL_StringBuffer_SC) == 0)
  371.                  StringBuffer_append_string_method = append_method;
  372.             else if (strcmp(signature, StringConstant::U8S_LP_Ljava_SL_lang_SL_Object_SC_RP_Ljava_SL_lang_SL_StringBuffer_SC) == 0)
  373.                  StringBuffer_append_object_method = append_method;
  374.         }
  375.  
  376.         if (! (StringBuffer_Init_method &&
  377.                StringBuffer_InitWithString_method &&
  378.                StringBuffer_toString_method &&
  379.                StringBuffer_append_char_array_method &&
  380.                StringBuffer_append_char_method &&
  381.                StringBuffer_append_boolean_method &&
  382.                StringBuffer_append_int_method &&
  383.                StringBuffer_append_long_method &&
  384.                StringBuffer_append_float_method &&
  385.                StringBuffer_append_double_method &&
  386.                StringBuffer_append_string_method &&
  387.                StringBuffer_append_object_method))
  388.         {
  389.             system_semantic -> ReportSemError(SemanticError::NON_STANDARD_LIBRARY_TYPE,
  390.                                               0,
  391.                                               0,
  392.                                               StringBuffer_type -> ContainingPackage() -> PackageName(),
  393.                                               StringBuffer_type -> ExternalName());
  394.         }
  395.     }
  396.  
  397.     return;
  398. }
  399.  
  400.  
  401. //
  402. // Create the unnamed package and set up global names.
  403. //
  404. void Control::ProcessUnnamedPackage()
  405. {
  406.     unnamed_package = external_table.InsertPackageSymbol(FindOrInsertName(US_EMPTY, wcslen(US_EMPTY)), NULL);
  407.  
  408.     //
  409.     // Create an entry for no_type. no_type is used primarily to signal an error
  410.     //
  411.     no_type = unnamed_package -> InsertSystemTypeSymbol(FindOrInsertName(US__QU__QU, wcslen(US__QU__QU)));
  412.     no_type -> SetSignature(Utf8_pool.FindOrInsert(U8S__DO, strlen(U8S__DO))); // give it some signature...
  413.     no_type -> outermost_type = no_type;
  414.     no_type -> SetOwner(unnamed_package);
  415.     no_type -> MarkBad();
  416.  
  417.     //
  418.     // Create an entry for the null type.
  419.     //
  420.     null_type = unnamed_package -> InsertSystemTypeSymbol(FindOrInsertName(US_null, wcslen(US_null)));
  421.     null_type -> outermost_type = null_type;
  422.     null_type -> SetOwner(unnamed_package);
  423.     null_type -> SetACC_PUBLIC();
  424.  
  425.     return;
  426. }
  427.  
  428.  
  429. void Control::ProcessPath()
  430. {
  431. #if defined(UNIX_FILE_SYSTEM) || defined(AMIGAOS_FILE_SYSTEM)
  432.     NameSymbol *dot_path_name_symbol = dot_name_symbol;
  433.  
  434.     //
  435.     // We need a place to start. Allocate a "." directory with no owner initially. (Hence, the null argument.)
  436.     // Allocate a "." path whose associated directory is the "." directory.
  437.     // Identify the "." path as the owner of the "." directory.
  438.     //
  439.     DirectorySymbol *default_directory = new DirectorySymbol(dot_name_symbol, NULL);
  440.     classpath.Next() = classpath_table.InsertPathSymbol(dot_path_name_symbol, default_directory);
  441.     default_directory -> ReadDirectory(); // Note that the default_directory is reset after it has been assigned the owner above.
  442.     system_directories.Next() = default_directory;
  443.  
  444.     system_table = new SystemTable();
  445.     struct stat status;
  446.     if ((::SystemStat(dot_name_symbol -> Utf8Name(), &status) == 0) && (status.st_mode & STAT_S_IFDIR))
  447.         system_table -> InsertDirectorySymbol(status.st_dev, status.st_ino, default_directory);
  448.  
  449. #elif defined(WIN32_FILE_SYSTEM)
  450.  
  451.     char *main_current_directory = option.GetMainCurrentDirectory();
  452.     int dot_path_name_length = strlen(main_current_directory);
  453.     wchar_t *dot_path_name = new wchar_t[dot_path_name_length + 1];
  454.     for (int i = 0; i < dot_path_name_length; i++)
  455.         dot_path_name[i] = main_current_directory[i];
  456.     dot_path_name[dot_path_name_length] = U_NULL;
  457.     NameSymbol *dot_path_name_symbol = FindOrInsertName(dot_path_name, dot_path_name_length);
  458.     delete [] dot_path_name;
  459.  
  460.     //
  461.     // We need a place to start. Allocate a "." directory with no owner initially. (Hence, the null argument.)
  462.     // Allocate a "." path whose associated directory is the "." directory.
  463.     // Identify the "." path as the owner of the "." directory.
  464.     //
  465.     DirectorySymbol *default_directory = new DirectorySymbol(dot_name_symbol, NULL);
  466.     classpath.Next() = classpath_table.InsertPathSymbol(dot_path_name_symbol, default_directory);
  467.     default_directory -> ReadDirectory(); // Note that the default_directory is reset after it has been assigned the owner above.
  468.     system_directories.Next() = default_directory;
  469. #endif
  470.  
  471.     //
  472.     //
  473.     //
  474.     if (option.classpath)
  475.     {
  476.         int max_path_name_length = strlen(option.classpath) + 1; // The longest possible path name we can encounter
  477.         wchar_t *path_name = new wchar_t[max_path_name_length + 1]; // +1 for '\0'
  478.  
  479.         wchar_t *input_name = NULL;
  480. #ifdef WIN32_FILE_SYSTEM
  481.         char * full_directory_name = NULL;
  482. #endif
  483.  
  484.         for (char *path = option.classpath, *path_tail = &path[strlen(path)]; path < path_tail; path++)
  485.         {
  486. #ifdef WIN32_FILE_SYSTEM
  487.             delete [] full_directory_name;
  488.             delete [] input_name;
  489. #endif
  490.             char *head;
  491.             for (head = path; path < path_tail && *path != ::PathSeparator(); path++)
  492.                 ;
  493.             *path = U_NULL; // If a seperator was encountered, replace it by \0 to terminate the string.
  494.             int input_name_length = path - head;
  495.  
  496.             int path_name_length = input_name_length;
  497.             for (int i = 0; i < path_name_length; i++)
  498.                 path_name[i] = head[i];
  499.             path_name[path_name_length] = U_NULL;
  500.  
  501. #if defined(UNIX_FILE_SYSTEM) || defined(AMIGAOS_FILE_SYSTEM)
  502.  
  503.             input_name = path_name;
  504.  
  505. #elif defined(WIN32_FILE_SYSTEM)
  506.  
  507.             input_name = NULL;
  508.             full_directory_name = NULL;
  509.             char disk = (input_name_length >= 2 && Case::IsAsciiAlpha(head[0]) && head[1] == U_COLON ? head[0] : 0);
  510.  
  511.             //
  512.             // Look for the directory. If it is found, update input_name and head.
  513.             //
  514.             option.SaveCurrentDirectoryOnDisk(disk);
  515.             if (SetCurrentDirectory(head))
  516.             {
  517.                 char tmp[1];
  518.                 DWORD directory_length = GetCurrentDirectory(0, tmp); // first, get the right size
  519.                 full_directory_name = new char[directory_length + 1];  // allocate the directory
  520.                 DWORD length = GetCurrentDirectory(directory_length, full_directory_name);
  521.                 if (length <= directory_length)
  522.                 {
  523.                     for (char *ptr = full_directory_name; *ptr; ptr++)
  524.                         *ptr = (*ptr != U_BACKSLASH ? *ptr : (char) U_SLASH); // turn '\' to '/'.
  525.  
  526.                     input_name_length = length;
  527.                     input_name = new wchar_t[input_name_length + 1];
  528.                     for (int k = 0; k < input_name_length; k++)
  529.                         input_name[k] = full_directory_name[k];
  530.                     input_name[input_name_length] = U_NULL;
  531.                     head = full_directory_name;
  532.                 }
  533.             }
  534.  
  535.             //
  536.             // Default input_name, in case we do not succeed in finding the directory
  537.             //
  538.             if (! input_name)
  539.             {
  540.                 input_name = new wchar_t[input_name_length + 1];
  541.                 for (int j = 0; j < input_name_length; j++)
  542.                     input_name[j] = path_name[j];
  543.                 input_name[input_name_length] = U_NULL;
  544.             }
  545.  
  546.             option.ResetCurrentDirectoryOnDisk(disk); // reset the current directory on disk
  547.             option.SetMainCurrentDirectory();         // reset the real current directory...
  548. #endif
  549.  
  550.             //
  551.             //
  552.             //
  553.             if (input_name_length > 0)
  554.             {
  555.                 NameSymbol *name_symbol = FindOrInsertName(path_name, path_name_length);
  556.  
  557.                 //
  558.                 // If a directory is specified more than once, ignore the duplicates.
  559.                 //
  560.                 if (classpath_table.FindPathSymbol(name_symbol))
  561.                 {
  562.                     if (name_symbol == dot_name_symbol)
  563.                     {
  564.                         dot_classpath_index = classpath.Length(); // The next index
  565.                         classpath.Next() = classpath[0];          // share the "." directory
  566.                         unnamed_package -> directory.Next() = classpath[0] -> RootDirectory();
  567.                     }
  568.  
  569.                     continue;
  570.                 }
  571.  
  572.                 //
  573.                 // Check whether or not the path points to a system directory. If not, assume it's a zip file
  574.                 //
  575.                 if (::SystemIsDirectory(head))
  576.                 {
  577.                     DirectorySymbol *dot_directory = ProcessSubdirectories(input_name, input_name_length);
  578.                     unnamed_package -> directory.Next() = dot_directory;
  579.                     classpath.Next() = classpath_table.InsertPathSymbol(name_symbol, dot_directory);
  580.                 }
  581.                 else
  582.                 {
  583.                     Zip *zipinfo = new Zip(*this, head);
  584.                     if (! zipinfo -> IsValid()) // If the zipfile is all screwed up, give up here !!!
  585.                     {
  586.                         wchar_t *name = new wchar_t[input_name_length + 1];
  587.                         for (int i = 0; i < input_name_length; i++)
  588.                             name[i] = input_name[i];
  589.                         name[input_name_length] = U_NULL;
  590.                         bad_zip_filenames.Next() = name;
  591.                     }
  592.  
  593.                     unnamed_package -> directory.Next() = zipinfo -> RootDirectory();
  594.  
  595.                     //
  596.                     // Create the new path symbol and update the class path with it.
  597.                     //
  598.                     PathSymbol *path_symbol = classpath_table.InsertPathSymbol(name_symbol, zipinfo -> RootDirectory());
  599.                     path_symbol -> zipfile = zipinfo;
  600.                     classpath.Next() = path_symbol;
  601.                 }
  602.             }
  603.         }
  604.  
  605. #ifdef WIN32_FILE_SYSTEM
  606.         delete [] full_directory_name;
  607.         delete [] input_name;
  608. #endif
  609.  
  610.         delete [] path_name;
  611.     }
  612.  
  613.     //
  614.     // TODO: If the user did not specify "." in the class path we assume it.
  615.     // javac makes that assumption also. Is that correct?
  616.     //
  617.     if (dot_classpath_index == 0)
  618.         unnamed_package -> directory.Next() = classpath[0] -> RootDirectory();
  619.  
  620.     return;
  621. }
  622.  
  623.  
  624. TypeSymbol *Control::GetPrimitiveType(wchar_t *name, char *signature)
  625. {
  626.     NameSymbol *name_symbol = FindOrInsertName(name, wcslen(name));
  627.     TypeSymbol *type = unnamed_package -> InsertSystemTypeSymbol(name_symbol);
  628.  
  629.     type -> SetSignature(Utf8_pool.FindOrInsert(signature, strlen(signature)));
  630.     type -> outermost_type = type;
  631.     type -> SetOwner(unnamed_package);
  632.     type -> SetACC_PUBLIC();
  633.     type -> MarkPrimitive();
  634.  
  635.     return type;
  636. }
  637.  
  638.  
  639. void Control::ProcessSystemInformation()
  640. {
  641.     //
  642.     // Add entry for system package
  643.     //
  644.     system_package = ProcessPackage(StringConstant::US_java_SL_lang);
  645.     java_util_package = ProcessPackage(StringConstant::US_java_SL_util);
  646.  
  647.     //
  648.     // Create an entry for each primitive type. Note that the type void is treated as a primitive.
  649.     //
  650.     void_type = GetPrimitiveType(US_void, U8S_V);
  651.     boolean_type = GetPrimitiveType(US_boolean, U8S_Z);
  652.     byte_type = GetPrimitiveType(US_byte, U8S_B);
  653.     char_type = GetPrimitiveType(US_char, U8S_C);
  654.     short_type = GetPrimitiveType(US_short, U8S_S);
  655.     int_type = GetPrimitiveType(US_int, U8S_I);
  656.     long_type = GetPrimitiveType(US_long, U8S_J);
  657.     float_type = GetPrimitiveType(US_float, U8S_F);
  658.     double_type = GetPrimitiveType(US_double, U8S_D);
  659.  
  660.     return;
  661. }
  662.  
  663.  
  664. DirectorySymbol *Control::GetOutputDirectory(FileSymbol *file_symbol)
  665. {
  666.     DirectorySymbol *directory_symbol;
  667.  
  668.     Control &control = file_symbol -> semantic -> control;
  669.     if (control.option.directory == NULL)
  670.         directory_symbol = file_symbol -> directory_symbol;
  671.     else
  672.     {
  673.         char *directory_prefix = control.option.directory;
  674.         int directory_prefix_length = strlen(directory_prefix),
  675.             utf8_name_length = file_symbol -> package -> PackageNameLength() * 3,
  676.             estimated_length = directory_prefix_length + utf8_name_length + 1; // +1 for slash
  677.  
  678.         char *directory_name = new char[estimated_length + 1]; // +1 for '\0'
  679.  
  680.         strcpy(directory_name, directory_prefix);
  681.  
  682.         if (file_symbol -> package != control.unnamed_package) // if there was a package declaration, then...
  683.         {
  684.             if (directory_prefix[directory_prefix_length - 1] != U_SLASH)
  685.                 strcat(directory_name, StringConstant::U8S__SL);
  686.             char *utf8_name = new char[utf8_name_length + 1];
  687.             (void) ConvertUnicodeToUtf8(file_symbol -> package -> PackageName(), utf8_name);
  688.             strcat(directory_name, utf8_name);
  689.             delete [] utf8_name;
  690.  
  691.             if (! ::SystemIsDirectory(directory_name)) // The directory does not yet exist.
  692.             {
  693.                 for (char *ptr = &directory_name[directory_prefix_length + 1]; *ptr; ptr++)
  694.                 {
  695.                     if (*ptr == U_SLASH) // all the slashes in a package_name are forward slashes
  696.                     {
  697.                         *ptr = U_NULL;
  698.                         if (! ::SystemIsDirectory(directory_name))
  699.                             ::SystemMkdir(directory_name);
  700.                         *ptr = U_SLASH; // restore slash
  701.                     }
  702.                 }
  703.                 ::SystemMkdir(directory_name);
  704.             }
  705.         }
  706.  
  707.         //
  708.         // Read the directory and insert the directory symbol. Note that since
  709.         // the original length computation was an estimate, we compute the real
  710.         // length here.
  711.         //
  712.         int length = strlen(directory_name);
  713.         wchar_t *name = new wchar_t[length + 1];
  714.         for (int i = 0; i < length; i++)
  715.             name[i] = directory_name[i];
  716.         name[length] = U_NULL;
  717.  
  718.         directory_symbol = control.ProcessSubdirectories(name, length);
  719.  
  720.         delete [] directory_name;
  721.     }
  722.  
  723.     return directory_symbol;
  724. }
  725.  
  726.  
  727. FileSymbol *Control::GetJavaFile(PackageSymbol *package, NameSymbol *name_symbol)
  728. {
  729.     FileSymbol *file_symbol = NULL;
  730.  
  731.     //
  732.     //
  733.     //
  734.     int length = name_symbol -> Utf8NameLength() + FileSymbol::java_suffix_length;
  735.     char *full_filename = new char[length + 1]; // +1 for \0
  736.     strcpy(full_filename, name_symbol -> Utf8Name());
  737.     strcat(full_filename, FileSymbol::java_suffix);
  738.  
  739.     DirectoryEntry *entry = NULL;
  740.     DirectorySymbol *directory_symbol = NULL;
  741.     for (int k = 0; k < package -> directory.Length(); k++)
  742.     {
  743.         directory_symbol = package -> directory[k];
  744.         if ((entry = directory_symbol -> FindEntry(full_filename, length)))
  745.             break;
  746.     }
  747.  
  748.     if (entry)
  749.     {
  750.         PathSymbol *path_symbol = directory_symbol -> PathSym();
  751.  
  752.         file_symbol = directory_symbol -> FindFileSymbol(name_symbol);
  753.         if (! ((file_symbol && file_symbol -> IsJava()) || path_symbol -> IsZip()))
  754.         {
  755.             file_symbol = directory_symbol -> InsertFileSymbol(name_symbol);
  756.  
  757.             file_symbol -> directory_symbol = directory_symbol;
  758.             file_symbol -> SetJava();
  759.             file_symbol -> mtime = entry -> Mtime();
  760.         }
  761.     }
  762.  
  763.     delete [] full_filename;
  764.  
  765.     return file_symbol;
  766. }
  767.  
  768.  
  769. FileSymbol *Control::GetFile(Control &control, PackageSymbol *package, NameSymbol *name_symbol)
  770. {
  771.     return control.option.classpath_search_order
  772.             ?    GetFileBoth(control, package, name_symbol)
  773.             :    GetFileFirst(control, package, name_symbol);
  774. }
  775.  
  776. FileSymbol *Control::GetFileBoth(Control &control, PackageSymbol *package, NameSymbol *name_symbol)
  777. {
  778.     FileSymbol *java_file_symbol = NULL, *class_file_symbol = NULL;
  779.  
  780.     //
  781.     // calculate a length that is large enough...
  782.     //
  783.     int class_length = name_symbol -> Utf8NameLength() + FileSymbol::class_suffix_length,
  784.     java_length = name_symbol -> Utf8NameLength() + FileSymbol::java_suffix_length;
  785.  
  786.     char *class_name = new char[class_length + 1]; // +1 for \0
  787.     strcpy(class_name, name_symbol -> Utf8Name());
  788.     strcat(class_name, FileSymbol::class_suffix);
  789.  
  790.     char *java_name = new char[java_length + 1]; // +1 for \0
  791.     strcpy(java_name, name_symbol -> Utf8Name());
  792.     strcat(java_name, FileSymbol::java_suffix);
  793.  
  794.     for (int k = 0; k < package -> directory.Length(); k++)
  795.     {
  796.         DirectorySymbol *directory_symbol = package -> directory[k];
  797.         bool foundBothEntries = false;
  798.         FileSymbol *file_symbol = directory_symbol -> FindFileSymbol(name_symbol);
  799.         if (! file_symbol)
  800.         {
  801.             PathSymbol *path_symbol = directory_symbol -> PathSym();
  802.             if (! path_symbol -> IsZip())
  803.             {
  804.                 DirectoryEntry *java_entry = directory_symbol -> FindEntry(java_name, java_length),
  805.                 *class_entry = (((! control.option.depend) || (java_entry == NULL))
  806.                                 ? directory_symbol -> FindEntry(class_name, class_length)
  807.                                 : (DirectoryEntry *) NULL);
  808.  
  809.                 if (java_entry || class_entry)
  810.                 {
  811.                     file_symbol = directory_symbol -> InsertFileSymbol(name_symbol);
  812.                     file_symbol -> directory_symbol = directory_symbol;
  813.  
  814.                     if (java_entry && ((! class_entry) || class_entry -> Mtime() < java_entry -> Mtime()))
  815.                     {
  816.                         file_symbol -> SetJava();
  817.                         file_symbol -> mtime = java_entry -> Mtime();
  818.                     }
  819.                     else
  820.                     {
  821.                         if (java_entry)
  822.                             file_symbol -> SetClass();
  823.                         else file_symbol -> SetClassOnly();
  824.                         file_symbol -> mtime = class_entry -> Mtime();
  825.                     }
  826.                 }
  827.  
  828.                 if (java_entry && class_entry)
  829.                     foundBothEntries = true; // flag case where both .java and class found in same path
  830.             }
  831.         }
  832.  
  833.         if (file_symbol)
  834.         {
  835.             if (file_symbol -> IsJava() && ! java_file_symbol)
  836.                 java_file_symbol = file_symbol; // if no .java file seen yet, note this one
  837.             else if (! class_file_symbol)
  838.                 class_file_symbol = file_symbol; // if no .class file seen yet, note this one
  839.  
  840.  
  841.             if (foundBothEntries == true || (java_file_symbol && class_file_symbol))
  842.                 break;      // both .java and .class seen, so no point in continuing the search
  843.         }
  844.     }
  845.  
  846.     delete [] java_name;
  847.     delete [] class_name;
  848.  
  849.     //
  850.     // If both .java and .class seen, do a mod time check to decide which one to deliver.
  851.     // Otherwise just return whichever kind we found, or NULL.
  852.     //
  853.     if (java_file_symbol && ((! class_file_symbol) || class_file_symbol -> mtime < java_file_symbol -> mtime))
  854.         return java_file_symbol;
  855.     else
  856.         return class_file_symbol;
  857. }
  858.  
  859. FileSymbol *Control::GetFileFirst(Control &control, PackageSymbol *package, NameSymbol *name_symbol)
  860. {
  861.     FileSymbol *file_symbol = NULL;
  862.  
  863.     //
  864.     // calculate a length that is large enough...
  865.     //
  866.     int class_length = name_symbol -> Utf8NameLength() + FileSymbol::class_suffix_length,
  867.         java_length = name_symbol -> Utf8NameLength() + FileSymbol::java_suffix_length;
  868.  
  869.     char *class_name = new char[class_length + 1]; // +1 for \0
  870.     strcpy(class_name, name_symbol -> Utf8Name());
  871.     strcat(class_name, FileSymbol::class_suffix);
  872.  
  873.     char *java_name = new char[java_length + 1]; // +1 for \0
  874.     strcpy(java_name, name_symbol -> Utf8Name());
  875.     strcat(java_name, FileSymbol::java_suffix);
  876.  
  877.     for (int k = 0; k < package -> directory.Length(); k++)
  878.     {
  879.         DirectorySymbol *directory_symbol = package -> directory[k];
  880.         file_symbol = directory_symbol -> FindFileSymbol(name_symbol);
  881.         if (file_symbol)
  882.              break;
  883.  
  884.         PathSymbol *path_symbol = directory_symbol -> PathSym();
  885.         if (! path_symbol -> IsZip())
  886.         {
  887.             DirectoryEntry *java_entry = directory_symbol -> FindEntry(java_name, java_length),
  888.                            *class_entry = (((! control.option.depend) || (java_entry == NULL))
  889.                                                                        ? directory_symbol -> FindEntry(class_name, class_length)
  890.                                                                        : (DirectoryEntry *) NULL);
  891.  
  892.             if (java_entry || class_entry)
  893.             {
  894.                 file_symbol = directory_symbol -> InsertFileSymbol(name_symbol);
  895.                 file_symbol -> directory_symbol = directory_symbol;
  896.  
  897.                 if (java_entry && ((! class_entry) || class_entry -> Mtime() < java_entry -> Mtime()))
  898.                 {
  899.                     file_symbol -> SetJava();
  900.                     file_symbol -> mtime = java_entry -> Mtime();
  901.                 }
  902.                 else
  903.                 {
  904.                     if (java_entry)
  905.                          file_symbol -> SetClass();
  906.                     else file_symbol -> SetClassOnly();
  907.                     file_symbol -> mtime = class_entry -> Mtime();
  908.                 }
  909.                 break;
  910.             }
  911.         }
  912.     }
  913.  
  914.     delete [] java_name;
  915.     delete [] class_name;
  916.  
  917.     return file_symbol;
  918. }
  919.  
  920.  
  921.  
  922. TypeSymbol *Control::GetType(PackageSymbol *package, wchar_t *name)
  923. {
  924.     NameSymbol *name_symbol = FindOrInsertName(name, wcslen(name));
  925.     TypeSymbol *type = package -> FindTypeSymbol(name_symbol);
  926.  
  927.     if (! type)
  928.     {
  929.         Control &control = *this;
  930.         FileSymbol *file_symbol = GetFile(control, package, name_symbol);
  931.         type = system_semantic -> ReadType(file_symbol, package, name_symbol, 0);
  932.     }
  933.     else if (type -> SourcePending())
  934.          ProcessHeaders(type -> file_symbol);
  935.  
  936.     return type;
  937. }
  938.  
  939.